home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / mui / bcc_src.lha / Parser / ParseBC.cpp < prev    next >
C/C++ Source or Header  |  1998-03-15  |  12KB  |  588 lines

  1. #include "ParseBC.h"
  2. #include "ClassDef.h"
  3. #include "MethodDef.h"
  4. #include "VarDef.h"
  5.  
  6. #include "Global.h"
  7.  
  8. #include <string.h>
  9.  
  10. short ParseBC::Start( void )
  11. {
  12.  
  13.     BCC_block_cnt = 0;
  14.  
  15.     ins_every.Insert( ofh );
  16.     ins_code.Insert( ofh );
  17.  
  18.     UpdateLineNo();
  19.  
  20.     reppar.Clear();
  21.     clref.Clear();
  22.     cd = 0;
  23.     
  24.     switches = 0;
  25.     
  26.     while( 1 ) {
  27.     
  28.         GetToken();
  29.         if( !TokLen ) break;
  30.         
  31.         if( BCC_block_cnt ) {
  32.     
  33.             short rcr;
  34.             rcr = FullCheck();
  35.             if( rcr == -1 ) return 0;
  36.             
  37. /*            rcr = NewDelCheck();
  38.             if( rcr == -1 ) return 0;*/
  39.  
  40.             rcr = ClassPtrDefinition( BCC_block[BCC_block_cnt-1].rep );
  41.             if( rcr == -1 ) return 0;
  42.             
  43.             if( chcmp( '}' ) && MBracket == BCC_block[BCC_block_cnt-1].brc ) {
  44.                 BCC_block_cnt--;
  45.                 delete BCC_block[BCC_block_cnt].rep;
  46.                 StopCopy();
  47.                 StartCopy();
  48.             }
  49.         
  50.         }
  51.         if( TokType == ALN ) {
  52.             if( TokLen == 6 && !strncmp( "Method", Tok, 6 ) ) {
  53.                 if( !DoMA() ) {
  54.                     if( !ErrorBuf ) Error( 12 );
  55.                     return 0;
  56.                 }
  57.                 switches = 0;
  58.             } else {
  59.             if( TokLen == 7 && !strncmp( "include", Tok, 7 ) ) {
  60.                 if( !DoHeader() ) {
  61.                     return 0;
  62.                 }
  63.                 
  64.             } else {
  65.             if( TokLen == 9 && !strncmp( "Attribute", Tok, 9 ) ) {
  66.                 if( !DoMA( 1 ) ) {
  67.                     if( !ErrorBuf ) Error( 12 );
  68.                     return 0;
  69.                 }
  70.                 switches = 0;
  71.             } else {
  72.             if( TokLen == 6 && !strncmp( "nodata", Tok, 6 ) ) {
  73.                 switches |= SW_NODATA;
  74.                 StopCopy();
  75.                 StartCopy();
  76.             } else {
  77.             if( TokLen == 6 && !strncmp( "custom", Tok, 6 ) ) {
  78.                 switches |= SW_CUSTOM;
  79.                 StopCopy();
  80.                 StartCopy();
  81.             } else {
  82.             if( TokLen == 8 && !strncmp( "presuper", Tok, 8 ) ) {
  83.                 switches |= SW_PRESUPER;
  84.                 StopCopy();
  85.                 StartCopy();
  86.             } else {
  87.             if( TokLen == 9 && !strncmp( "postsuper", Tok, 9 ) ) {
  88.                 switches |= SW_POSTSUPER;
  89.                 StopCopy();
  90.                 StartCopy();
  91.             } else {
  92.             if( TokLen == 10 && !strncmp( "supercheck", Tok, 10 ) ) {
  93.                 switches |= SW_SUPERCHECK;
  94.                 StopCopy();
  95.                 StartCopy();
  96.             } else {
  97.             if( TokLen == 11 && !strncmp( "noearlydata", Tok, 11 ) ) {
  98.                 switches |= SW_NOEARLYDATA;
  99.                 StopCopy();
  100.                 StartCopy();
  101.             } else {
  102.             if( TokLen == 9 && !strncmp( "cleardata", Tok, 9 ) ) {
  103.                 switches |= SW_CLEARDATA;
  104.                 StopCopy();
  105.                 StartCopy();
  106.             } else {
  107.             if( TokLen == 5 && !strncmp( "super", Tok, 5 ) ) {
  108.                 switches |= SW_SUPER;
  109.                 StopCopy();
  110.                 StartCopy();
  111.             } else {
  112.             if( TokLen == 8 && !strncmp( "BCCBlock", Tok, 8 ) ) {
  113.                 StopCopy();
  114.                 
  115.                 if( BCC_block_cnt >= MAXBCCBLOCKS ) {
  116.                     Error( 24 );
  117.                     return 0;
  118.                 }
  119.                 
  120.                 BCC_block[BCC_block_cnt].brc = MBracket;
  121.  
  122.                 GetToken();
  123.                 if( !TokLen ) return 0;
  124.             
  125.                 if( !chcmp( '{' ) ) {
  126.                     Error( 2 );
  127.                     return 0;
  128.                 }
  129.  
  130.                 BCC_block[BCC_block_cnt].rep = new Replace;
  131.                 
  132.                 BCC_block_cnt++;
  133.                 
  134.                 StartCopy();
  135.             } else switches = 0;
  136.             }
  137.             }
  138.             }
  139.             }
  140.             }
  141.             }
  142.             }
  143.             }
  144.             }
  145.             }
  146.             }
  147.         }
  148.  
  149.         
  150.     }
  151.     
  152.     if( BCC_block_cnt ) {
  153.         short f;
  154.         for( f = 0; f < BCC_block_cnt; f++ ) delete BCC_block[f].rep;
  155.         Error( 25 );
  156.         return 0;
  157.     }
  158.     
  159.     FScan( ClassDef, c1, &ClassList ) {
  160.         if( !stricmp( sfname, c1->Name ) ) {
  161.             cd = c1;
  162.             CreateDisp( ofh );
  163.         }
  164.     }
  165.     
  166.     return 1;
  167.  
  168. }
  169.  
  170. short ParseBC::DoMA( short attr )
  171. {
  172.  short BLevel;
  173.  short mdspec = 0, passmsg;
  174.  MethodDef *md;
  175.  
  176.     reppar.Clear();
  177.     clref.Clear();
  178.  
  179.     StopCopy();
  180.  
  181.     GetToken();
  182.     if( !TokLen ) return 0;
  183.  
  184.     if( TokLen == 3 && !strncmp( "Set", Tok, 3 ) ) switches |= SW_SET;
  185.     else if( TokLen == 3 && !strncmp( "Get", Tok, 3 ) ) switches |= SW_GET;
  186.     else if( TokLen == 4 && !strncmp( "Init", Tok, 4 ) ) switches |= SW_INIT;
  187.  
  188.     if( switches & (SW_SET|SW_GET|SW_INIT) ) {
  189.         GetToken();
  190.         if( !TokLen ) return 0;
  191.     }
  192.  
  193.     cd = (ClassDef*)(ClassList.FindItem( Tok, TokLen ));
  194.     
  195.     if( !cd ) {
  196.         Error( 6 );
  197.         return 0;
  198.     }
  199.  
  200.     if( !IsReferenced( "data", &cd->rep ) ) switches |= SW_NODATA;
  201.     if( attr ) passmsg = IsReferenced( "msg" );
  202.  
  203.     GetToken();
  204.     if( !TokLen ) return 0;
  205.     
  206.     if( TokLen != 2 || strncmp( Tok, "::", 2 ) ) {
  207.         Error( 7 );
  208.         return 0;
  209.     }
  210.  
  211.     GetToken();
  212.     if( !TokLen ) return 0;
  213.  
  214.     BLevel = MBracket;
  215.  
  216.     switches |= stricmp( sfname, cd->Name ) ? 0 : SW_LOCAL;
  217.  
  218.     if( !attr ) {
  219.     /* Method */
  220.  
  221.     if( TokLen == strlen( cd->Name ) && !strncmp( cd->Name, Tok, TokLen ) ) {
  222.         md = new MethodDef( "OM_NEW", 6, 0, switches );
  223.         cd->AddTail( (Family*)md );
  224.         mdspec = 1;
  225.     } else {
  226.  
  227.     if( TokLen == strlen( cd->Name )+1 && *Tok == '~' && !strncmp( cd->Name, Tok+1, TokLen-1 ) ) {
  228.         md = new MethodDef( "OM_DISPOSE", 10, 0, switches );
  229.         cd->AddTail( (Family*)md );
  230.         mdspec = 2;
  231.     } else {
  232.  
  233.     if( switches & SW_SUPER ) {
  234.         md = new MethodDef( Tok, TokLen, 0, switches );
  235.         cd->AddTail( (Family*)md );
  236.     } else {
  237.         md = (MethodDef*)(cd->FindItem( Tok, TokLen ));
  238.         md->switches |= switches;
  239.     }
  240.     
  241.     }
  242.     
  243.     }
  244.     
  245.     if( !md ) {
  246.         Error( 8 );
  247.         return 0;
  248.     }
  249.     
  250.     if( md->switches & SW_VIRTUAL ) {
  251.         Error( 17 );
  252.         return 0;
  253.     }
  254.     
  255.     switches |= md->switches;
  256.  
  257. /*
  258.     if( mdspec == 1 ) {
  259.         FScan( VarDef, vd, &(cd->Var) ) {
  260.             if( (vd->switches & SW_INIT) && !(vd->switches & (SW_VIRTUAL|SW_SIMPLE)) ) {
  261.                 fprintf( ofh, "a%s%s%s( IClass*, Object*, void* );\n", cd->Name, vd->Name, vd->SGIName( SW_INIT ) );
  262.             }
  263.         }
  264.     }
  265. */
  266.  
  267.     /* Parameters */
  268.  
  269.     if( switches & SW_LOCAL ) fprintf( ofh, "static " );
  270.     fprintf( ofh, "unsigned long m%s%s( struct IClass *cl, Object *obj, ", cd->Name, md->Name );
  271.     
  272.     short ret;
  273.     ret = Params();
  274.     if( ret == -1 ) return 0;
  275.     if( !ret ) fprintf( ofh, "%s msg", md->msgtype );
  276.     else md->msgtype = "void*";
  277.     
  278.     fprintf( ofh, " )\n{\n" );
  279.  
  280.     if( EarlyCode() == -1 ) return 0;
  281.  
  282.     
  283.     if( !(switches & SW_CUSTOM) ) {
  284.     
  285.         if( mdspec == 1 ) fprintf( ofh, " unsigned long _ret;\n" );
  286.         else fprintf( ofh, " unsigned long _ret = 1;\n" );
  287.     
  288.     /* OM_NEW */
  289.     if( mdspec == 1 ) {
  290.  
  291.         if( !IsReferenced( "data", &cd->rep, 1 ) ) switches |= SW_NOEARLYDATA;
  292.  
  293.         InsertIAttrPre( ofh );
  294.     
  295.         if( chcmp( ':' ) ) {
  296.  
  297.             if( !(switches & SW_NODATA) ) {
  298.                 if( switches & SW_NOEARLYDATA ) {
  299.                     fprintf( ofh, " %sData *data;\n", cd->Name );
  300.                 } else {
  301.                     fprintf( ofh, " %sData *data, _tdata;\n data = &_tdata;\n", cd->Name );
  302.                     InitData();
  303.                 }
  304.             }
  305.  
  306.             fprintf( ofh, " obj = (Object*)BCC_DoSuperNew( cl, obj,\n" );
  307.  
  308.             UpdateLineNo();
  309.  
  310.             StartCopy();
  311.         
  312.             while( 1 ) {
  313.             
  314.                 GetToken();
  315.                 if( !TokLen ) return 0;
  316.  
  317.                 short rcr;
  318.                 rcr = FullCheck( );
  319.                 if( rcr == -1 ) return 0;
  320.  
  321.                 if( chcmp( '{' ) ) break;
  322.  
  323.             }
  324.             
  325.             StopCopy();
  326.             
  327.             fprintf( ofh, ",\n TAG_MORE, (unsigned long)msg->ops_AttrList,\n TAG_DONE );\n" );
  328.             
  329.             fprintf( ofh, " _ret = (unsigned long)obj;\n if( !obj ) return 0;\n" );
  330.             if( !(switches & SW_NODATA ) ) {
  331.                 if( switches & SW_NOEARLYDATA ) {
  332.                     fprintf( ofh, " data = INST_DATA( cl, obj );\n", cd->Name );
  333.                     InitData();
  334.                 } else fprintf( ofh, " data = INST_DATA( cl, obj );\n memcpy( data, &_tdata, sizeof( %sData ) );\n", cd->Name );
  335.             }
  336.             InsertIAttr( ofh );
  337.  
  338.         } else {
  339.             pDataDef();
  340.             fprintf( ofh, " obj = (Object*)DoSuperMethodA( cl, obj, (Msg)msg );\n" );
  341.             fprintf( ofh, " _ret = (unsigned long)obj;\n if( !obj ) return 0;\n" );
  342.             if( !(switches & SW_NODATA ) ) {
  343.                 fprintf( ofh, " data = INST_DATA( cl, obj );\n" );
  344.                 InitData();
  345.             }
  346.             InsertIAttr( ofh );
  347.         }
  348.     /* Other methods */
  349.     } else {
  350.         pDataDefAssign();
  351.         if( switches & SW_PRESUPER ) {
  352.             fprintf( ofh, " _ret = DoSuperMethodA( cl, obj, (Msg)msg );\n" );
  353.             if( switches & SW_SUPERCHECK ) fprintf( ofh, " if( !_ret ) return 0;\n" );
  354.         }
  355.     }
  356.     
  357.     }
  358.     
  359.     } else {
  360.     /* Attribute mode */
  361.     
  362.         VarDef *vd;
  363.  
  364.         if( switches & SW_SUPER ) {
  365.             vd = new VarDef( Tok, TokLen, switches );
  366.             cd->Var.AddTail( (Family*)vd );
  367.         } else 
  368.         if( !(vd = (VarDef*)((TextItem*)&cd->Var)->FindItem( Tok, TokLen )) ) {
  369.             Error( 11 );
  370.             return 0;
  371.         }
  372.         
  373.         vd->switches |= switches;
  374.  
  375.         if( vd->switches & SW_SIMPLE ) {
  376.             Error( 14 );
  377.             return 0;
  378.         }
  379.         
  380.         if( vd->switches & SW_VIRTUAL ) {
  381.             Error( 17 );
  382.             return 0;
  383.         }
  384.  
  385.         short CLevel = CBracket;
  386.         
  387.         GetToken();
  388.         if( !TokLen ) return 0;
  389.         
  390.         short ret;
  391.         unsigned short sw = switches;
  392.         ret = GetSGI( &sw );
  393.         if( ret == -1 ) return 0;
  394.         
  395.         if( !((sw & (SW_SET|SW_INIT)) ^ (SW_SET|SW_INIT)) ) sw |= SW_SAMESI;
  396.         
  397.         if( ( sw & (SW_SET|SW_INIT) ) && ( sw & SW_GET ) ) {
  398.             Error( 23 );
  399.             return 0;
  400.         }
  401.         
  402.         vd->switches |= sw;
  403.  
  404.         if( !(vd->switches & (SW_SET|SW_GET|SW_INIT)) ) {
  405.             Error( 10 );
  406.             return 0;
  407.         }
  408.  
  409.         if( passmsg ) vd->passmsg |= sw & (SW_SET|SW_GET|SW_INIT);
  410.         else vd->passmsg &= 0xffff - (sw & (SW_SET|SW_GET|SW_INIT));
  411.  
  412.  
  413.         fprintf( ofh, "void a%s%s", cd->Name, vd->Name );
  414.         if( sw & SW_SAMESI ) fprintf( ofh, "SI" );
  415.         else if( sw & SW_GET ) fprintf( ofh, "Get" );
  416.         else if( sw & SW_SET ) fprintf( ofh, "Set" );
  417.         else fprintf( ofh, "Init" );
  418.         fprintf( ofh, "( struct IClass *cl, Object *obj, struct { unsigned long ti_Tag;  " );
  419.         
  420.         if( chcmp( '(' ) ) {
  421.         
  422.             StartCopy();
  423.         
  424.             short c_line;
  425.             
  426.             c_line = LineN;
  427.         
  428.             short loop = 0;
  429.             while( 1 ) {
  430.     
  431.                 GetToken();
  432.                 if( !TokLen ) return 0;
  433.                 
  434.                 if( c_line != LineN ) {
  435.                     Error( 21 );
  436.                     return 0;
  437.                 }
  438.                 
  439.                 short ret;
  440.                 ret = ClassPtrDefinition( &clref, 1, 1 );
  441.                 if( ret == -1 ) return 0;
  442.  
  443.                 if( chcmp( ')' ) && CBracket == CLevel ) {
  444.                     if( !loop ) { Error( 27 ); return 0; } 
  445.                     break;
  446.                 }
  447.                 
  448.                 loop = 1;
  449.  
  450.             }
  451.             
  452.             StopCopy();
  453.  
  454.             String Buf( "(tag->" );
  455.             Buf += PrevTok;
  456.             Buf += ")";
  457.             reppar.Add( PrevTok, 0, (char*)Buf, 0 );
  458.             
  459.             GetToken();
  460.             if( !TokLen ) return 0;
  461.             
  462.         } else {
  463.             if( sw & SW_GET ) {
  464.                 fprintf( ofh, " unsigned long *store" );
  465.                 reppar.Add( "store", 0, "(tag->store)", 0 );
  466.             }
  467.             else {
  468.                 fprintf( ofh, " unsigned long value" );
  469.                 reppar.Add( "value", 0, "(tag->value)", 0 );
  470.             }
  471.         }
  472.         
  473.         char *pmsg = "";
  474.         if( vd->passmsg & sw ) {
  475.             if( sw & (SW_SET|SW_INIT) ) pmsg = ", struct opSet* msg";
  476.             if( sw & (SW_GET) ) pmsg = ", struct opGet* msg";
  477.         }
  478.         
  479.         fprintf( ofh, " ; } *tag%s )\n{\n", pmsg );
  480.  
  481.         pDataDefAssign();
  482.  
  483.     }
  484.  
  485.     if( !chcmp( '{' ) ) {
  486.         Error( 2 );
  487.         return 0;
  488.     }
  489.  
  490.     fprintf( ofh, "{\n /* UC Beg */\n" );
  491.     
  492.     UpdateLineNo();
  493.  
  494.     StartCopy();
  495.     
  496.     short wasmret = 0;
  497.     
  498.     String objrefbuf( cd->type );
  499.     objrefbuf += cd->Name;
  500.     clref.Add( "obj", 3, (char*)objrefbuf, 0 );
  501.  
  502.     InitClassPtrDef();
  503.  
  504.     /* Inside code */        
  505.     while( 1 ) {
  506.     
  507.         again:
  508.  
  509.         GetToken();
  510.         if( !TokLen ) break;
  511.         
  512.         short rcr;
  513.  
  514.         rcr = FullCheck( );
  515.         if( rcr == -1 ) return 0;
  516.         if( rcr ) goto again;
  517.  
  518.         if( chcmp( '}' ) && MBracket == BLevel ) break;
  519.  
  520.         rcr = ClassPtrDefinition( &clref );
  521.         if( rcr == -1 ) return 0;
  522.         if( rcr ) goto again;
  523.  
  524.         if( TokLen == 7 && !strncmp( Tok, "mreturn", 7 ) ) {
  525.             StopCopy();
  526.             fprintf( ofh, "{ _ret = " );
  527.             StartCopy();
  528.             
  529.             while( 1 ) {
  530.                 GetToken();
  531.                 if( !TokLen ) return 0;
  532.                 
  533.                 if( chcmp( ';' ) ) break;
  534.             }
  535.             
  536.             StopCopy();
  537.             StartCopy();
  538.             
  539.             fprintf( ofh, "; goto %s_exit; } ", md->Name );
  540.             wasmret = 1;
  541.         }
  542.     
  543.     }
  544.  
  545.     fprintf( ofh, "\n}\n /* UC End */\n" );
  546.     
  547.     if( !(switches & SW_CUSTOM) && !attr ) {
  548.     
  549.         fprintf( ofh, "%s_exit:\n", md->Name );
  550.  
  551.         if( mdspec == 1 ) {
  552.             if( wasmret ) fprintf( ofh, " if( !_ret ) CoerceMethod( cl, obj, OM_DISPOSE );\n" );
  553.         } else
  554.         if( switches & SW_POSTSUPER ) {
  555.             if( switches & SW_SUPERCHECK ) fprintf( ofh, " if( !_ret ) return 0;\n" );
  556.             fprintf( ofh, " _ret = DoSuperMethodA( cl, obj, (Msg)msg );\n" );
  557.         }
  558.         
  559.         fprintf( ofh, "return _ret;\n" );
  560.     
  561.     }
  562.  
  563.  
  564.     UpdateLineNo();
  565.     
  566.     cd = 0;
  567.     reppar.Clear();
  568.     clref.Clear();
  569.  
  570.     return 1;
  571.  
  572. }
  573.  
  574. void ParseBC::InitData( void )
  575. {
  576.     char *var, *val;
  577.     
  578.     if( switches & SW_CLEARDATA ) fprintf( ofh, " memset( data, 0, sizeof( %sData ) );\n", cd->Name );
  579.  
  580.     cd->rep.InitGetExtra();
  581.     
  582.     while( var = cd->rep.GetExtra( &val) ) {
  583.     
  584.         fprintf( ofh, " %s = %s;\n", var, val );
  585.     
  586.     }
  587.  
  588. }